package bma.common.langutil.jmshell.jvm;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.ThreadMXBean;
import java.text.DecimalFormat;

import bma.common.langutil.core.SizeUtil;
import bma.common.langutil.core.SizeUtil.Unit;
import bma.common.langutil.jmshell.Session;
import bma.common.langutil.jmshell.cmdopt.CommandOptionParser;
import bma.common.langutil.jmshell.command.AbstractSimpleCommandProcessor;

public class JVMRuntimeCommand extends AbstractSimpleCommandProcessor {

	public JVMRuntimeCommand() {
		super("runtime");
	}

	@Override
	public CommandOptionParser createCommandOption(Session session) {
		CommandOptionParser r = new CommandOptionParser();
		r.addBooleanOption('d', "detail", "show detail info");
		return r;
	}

	@Override
	public boolean processCommand(Session session, String cmd,
			CommandOptionParser options) {
		runtimeInfo(session, options);
		return true;
	}

	public void runtimeInfo(Session s, CommandOptionParser options) {
		Runtime rt = Runtime.getRuntime();
		int ap = rt.availableProcessors();
		long freem = rt.freeMemory();
		long maxm = rt.maxMemory();
		long totalm = rt.totalMemory();

		String osname = System.getProperty("os.name");
		String osarch = System.getProperty("os.arch");
		String osversion = System.getProperty("os.version");

		ThreadMXBean tb = ManagementFactory.getThreadMXBean();

		DecimalFormat df = new DecimalFormat("00.00");

		StringBuilder buf = new StringBuilder();
		buf.append("[runtime]\n");
		buf.append("OS           = ").append(osname).append("(")
				.append(osversion).append(",").append(osarch).append(")");
		buf.append("\n");
		buf.append("CPU          = ").append(ap).append("\n");
		buf.append("threads      = ").append(tb.getThreadCount()).append("\n");
		buf.append("peak threads = ").append(tb.getPeakThreadCount())
				.append("\n");
		buf.append("free  memory = ").append(freem).append("(")
				.append(SizeUtil.convert(freem, 1024, Unit.M)).append(") ");
		buf.append("\n");
		buf.append("used  memory = ").append(totalm - freem).append("(")
				.append(SizeUtil.convert((totalm - freem), 1024, Unit.M))
				.append(") ");
		buf.append(df.format(100 - freem * 100.0f / totalm)).append("%");
		buf.append("\n");
		buf.append("total memory = ").append(totalm).append("(")
				.append(SizeUtil.convert(totalm, 1024, Unit.M)).append(") ");
		buf.append(df.format(totalm * 100.0f / maxm)).append("%");
		buf.append("\n");
		buf.append("max   memory = ").append(maxm).append("(")
				.append(SizeUtil.convert(maxm, 1024, Unit.M)).append(") ")
				.append("\n");

		if (options.getOptionValue("detail", Boolean.FALSE)) {
			MemoryMXBean mb = ManagementFactory.getMemoryMXBean();
			MemoryUsage mu1 = mb.getHeapMemoryUsage();
			MemoryUsage mu2 = mb.getNonHeapMemoryUsage();

			buf.append("   heap usage= ").append(mu1).append("\n");
			buf.append("nonheap usage= ").append(mu2).append("\n");
		}

		s.write(buf.toString());
	}
}